package taskTracker.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import org.j4me.logging.Log;

/**
 * A class that holds one of the settings of the application.
 * @author aseldawy
 *
 */
public class Setting implements Serializable{
	/**Name that is shown to user*/
	public String name;
	
	/**A generic object that holds whatever the value of this field*/
	public Object value;

	/**
	 * Tells what type of this field is.
	 * It helps viewing the correct GUI component to enter it.
	 * It also limits the possible values entered to value.
	 * Possible values for the field type are:
	 * <table>
	 * 	<tr><th>Type</th><th>GUI component</th><th>Possible values</th></tr>
	 *  <tr><td>String</td><td>TextField</td><td>Any string value</td></tr>
	 *  <tr><td>Integer</td><td>TextField</td><td>Any integer value (+ve or -ve)</td></tr>
	 *  <tr><td>Boolean</td><td>ChoiceGroup</td><td>True or False</td></tr>
	 *  <tr><td>multiple\n...\n...)</td><td>ChoiceGroup</td><td>One of the string values provided in type (in rows starting from 2)</td></tr>
	 *  <tr><td>hidden</td><td>none</td><td>Any object</td></tr>
	 * </table>
	 */
	public String type;

	/**Category of this field*/
	public String category;
	
	
	/**
	 * Create a new setting.
	 * @param name
	 * @param value
	 * @param type
	 * @param category
	 */
	public Setting(String name, Object value, String type, String category) {
		super();
		this.name = name;
		this.value = value;
		this.type = type;
		this.category = category;
	}

	public Setting(DataInputStream dis) throws IOException {
		this.name = dis.readUTF();
		this.value = Helper.readObject(dis);
		this.type = dis.readUTF();
		this.category = dis.readUTF();
	}

	/**
	 * Writes this setting to disk.
	 */
	public void serialize(DataOutputStream dos) throws IOException {
		dos.writeUTF(name);
		Helper.writeObject(dos, value);
		dos.writeUTF(type);
		dos.writeUTF(category);
	}
	
	/**
	 * Write all given settings to a record store
	 * @param settings
	 */
	public static void saveSettings(Setting[] settings) {
		ByteArrayOutputStream bOutputStream = new ByteArrayOutputStream() ;
		DataOutputStream dos = new DataOutputStream(bOutputStream);

		try {
			dos.writeInt(settings.length);
			for (int i = 0; i < settings.length; i++) {
				settings[i].serialize(dos);
			}
			
			dos.close();
			
			// Write to record store
			byte[] byteArray= bOutputStream.toByteArray();
			taskTracker.util.Helper.writeRS(byteArray, "settings", true);
		} catch (IOException e) {
			Log.error("Error in save settings", e);
		}
	}
	
	/**
	 * Load settings from disk
	 * @return
	 */
	public static Setting[] loadSettings() {
		byte[] data = taskTracker.util.Helper.readRS("settings");
		
		Setting[] settings = null;
		if (data != null) {
			ByteArrayInputStream bInputStream = new ByteArrayInputStream(data);
			DataInputStream dis = new DataInputStream(bInputStream);
			
			try {
				settings = new Setting[dis.readInt()];
				
				for (int i = 0; i < settings.length; i++) {
					settings[i] = new Setting(dis);
				}
			} catch (IOException e) {
				Log.error("Error in load settings", e);
			}
		}
		return settings;
	}
}
